home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / WATER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  8.0 KB  |  323 lines

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6.  
  7. /* Some <math.h> files do not define M_PI... */
  8. #ifndef M_PI
  9. #define M_PI 3.14159265358979323846
  10. #endif
  11.  
  12. #ifndef __sgi
  13. /* Most math.h's do not define float versions of the math functions. */
  14. #define expf(x) ((float)exp((x)))
  15. #define sinf(x) ((float)sin((x)))
  16. #endif
  17.  
  18. static int rgb;
  19. static int mesh = 1;
  20. static float ttrans[2];
  21. static float transx, transy, rotx, roty;
  22. static float amplitude = 0.03;
  23. static float freq = 5.0f;
  24. static float phase = .00003;
  25. static int ox = -1, oy = -1;
  26. static int show_t = 1;
  27. static int mot;
  28. #define PAN    1
  29. #define ROT    2
  30.  
  31. void
  32. pan(int x, int y) {
  33.     transx +=  (x-ox)/500.;
  34.     transy -= (y-oy)/500.;
  35.     ox = x; oy = y;
  36.     glutPostRedisplay();
  37. }
  38.  
  39. void
  40. rotate(int x, int y) {
  41.     rotx += x-ox;
  42.     if (rotx > 360.) rotx -= 360.;
  43.     else if (rotx < -360.) rotx += 360.;
  44.     roty += y-oy;
  45.     if (roty > 360.) roty -= 360.;
  46.     else if (roty < -360.) roty += 360.;
  47.     ox = x; oy = y;
  48.     glutPostRedisplay();
  49. }
  50.  
  51. void
  52. motion(int x, int y) {
  53.     if (mot == PAN) pan(x, y);
  54.     else if (mot == ROT) rotate(x,y);
  55. }
  56.  
  57. void
  58. mouse(int button, int state, int x, int y) {
  59.     if(state == GLUT_DOWN) {
  60.     switch(button) {
  61.     case GLUT_LEFT_BUTTON:
  62.         mot = PAN;
  63.         motion(ox = x, oy = y);
  64.         break;
  65.     case GLUT_MIDDLE_BUTTON:
  66.         mot = ROT;
  67.         motion(ox = x, oy = y);
  68.         break;
  69.     case GLUT_RIGHT_BUTTON:
  70.         break;
  71.     }
  72.     } else if (state == GLUT_UP) {
  73.     mot = 0;
  74.     }
  75. }
  76.  
  77. void toggle_t(void) {
  78.     show_t ^= 1;
  79. }
  80.  
  81. void ffunc(void) { freq *= 2.f; }
  82. void Ffunc(void) { freq /= 2.f; }
  83. void mfunc(void) { mesh ^= 1; }
  84.  
  85. void wire(void) {
  86.     static int w;
  87.     if (w ^= 1) {
  88.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  89.     glEnable(GL_BLEND);
  90.     } else {
  91.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  92.     glDisable(GL_BLEND);
  93.     }
  94. }
  95.  
  96. void light(void) {
  97.     static int l;
  98.     if (l ^= 1)
  99.     glEnable(GL_LIGHTING);
  100.     else
  101.     glDisable(GL_LIGHTING);
  102. }
  103.  
  104. void up(void) { amplitude += .01; }
  105. void down(void) { amplitude -= .01; }
  106. void left(void) { phase -= .00001; }
  107. void right(void) { phase += .00001; }
  108.  
  109. void
  110. animate(void) {
  111.     ttrans[0] += .005f;
  112.     if (ttrans[0] == 1.0f) ttrans[0] = 0.0f;
  113.     ttrans[1] -= .0025f;
  114.     if (ttrans[1] <= 0.0f) ttrans[1] = 1.0f;
  115.     glutPostRedisplay();
  116. }
  117.  
  118. void xfunc(void) {
  119.     static state = 1;
  120.     glutIdleFunc((state ^= 1) ? animate : NULL);
  121. }
  122.  
  123. void help(void) {
  124.     printf("Usage: water [image]\n");
  125.     printf("'h'            - help\n");
  126.     printf("'l'            - toggle lighting\n");
  127.     printf("'f'            - increase frequency\n");
  128.     printf("'F'            - decrease frequency\n");
  129.     printf("'m'            - toggle mesh\n");
  130.     printf("'t'            - toggle wireframe\n");
  131.     printf("'x'            - toggle water motion\n");
  132.     printf("'UP'           - increase amplitude\n");
  133.     printf("'DOWN'         - decrease amplitude\n");
  134.     printf("'RIGHT'        - increase phase change\n");
  135.     printf("'LEFT'         - decreae phase change\n");
  136.     printf("left mouse     - pan\n");
  137.     printf("middle mouse   - rotate\n");
  138. }
  139.  
  140. void init(char *filename) {
  141.     GLfloat cloud_color[4] = { 1., 1., 1., 0., };
  142.     GLfloat fog_color[4], fog_density = 0.05, density, far_cull;
  143.     unsigned *image;
  144.     int width, height, components;
  145.     if (filename) {
  146.     image = read_texture(filename, &width, &height, &components);
  147.     if (image == NULL) {
  148.         fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  149.             filename);
  150.         exit(EXIT_FAILURE);
  151.     } else {
  152.         printf("%d x %d image loaded\n", width, height);
  153.     }
  154.     if (components < 3) rgb = 0;
  155.     } else {
  156.     int i, j;
  157.     unsigned char *img;
  158.     components = 4; width = height = 512;
  159.     image = (unsigned *) malloc(width*height*sizeof(unsigned));
  160.     img = (unsigned char *)image;
  161.     for (j = 0; j < height; j++)
  162.         for (i = 0; i < width; i++) {
  163.         int w2 = width/2, h2 = height/2;
  164.         if (i & 32)
  165.             img[4*(i+j*width)+0] = 0xff;
  166.         else
  167.             img[4*(i+j*width)+1] = 0xff;
  168.         if (j&32)
  169.             img[4*(i+j*width)+2] = 0xff;
  170.         if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 &&
  171.             (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff;
  172.         }
  173.  
  174.     }
  175.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  176.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  177.     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cloud_color);
  178.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  179.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  180.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  181.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  182.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  183.                  height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  184.                  image);
  185.     glEnable(GL_TEXTURE_2D);
  186.     glMatrixMode(GL_PROJECTION);
  187.     glLoadIdentity();
  188.     gluPerspective(50.,1.,.1,far_cull = 10.);
  189.     glMatrixMode(GL_MODELVIEW);
  190.     glLoadIdentity();
  191.     glTranslatef(0.,0.,-5.5);
  192.  
  193.     density = 1.- expf(-5.5 * fog_density * fog_density *
  194.                   far_cull * far_cull);
  195.  
  196. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  197. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  198.     density = MAX(MIN(density, 1.), 0.);
  199.  
  200.     fog_color[0] = .23 + density *.57;
  201.     fog_color[1] = .35 + density *.45;
  202.     fog_color[2] = .78 + density *.22;
  203.  
  204.     glClearColor(fog_color[0], fog_color[1], fog_color[2], 1.f);
  205.  
  206.     glFogi(GL_FOG_MODE, GL_EXP2);
  207.     glFogf(GL_FOG_DENSITY, fog_density);
  208.     glFogfv(GL_FOG_COLOR, fog_color);
  209.     if (fog_density > 0)
  210.     glEnable(GL_FOG);
  211.     glLineWidth(2.0f);
  212.     glEnable(GL_LINE_SMOOTH);
  213.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  214. }
  215.  
  216. void draw_mesh(void) {
  217.     if (mesh) {
  218.     glBegin(GL_QUADS);
  219.     glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f);
  220.     glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f,  1.f);
  221.     glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f,  1.f);
  222.     glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f);
  223.     glEnd();
  224.     } else {
  225. #define MESH 32
  226.     int i, j;
  227.     static float off;
  228.     float d = 1.f/MESH;
  229.     for(i = 0; i < MESH; i++) {
  230.         glBegin(GL_TRIANGLE_STRIP);
  231.         for(j = 0; j < MESH; j++) {
  232.         float s = (float)j*d;
  233.         float t = (float)i*d;
  234.         float x = -1.0 + 2.f*s;
  235.         float z = -1.0 + 2.f*t;
  236.         float y = amplitude*sinf(freq*2.f*M_PI*t+off);
  237.         glTexCoord2f(s, t); glVertex3f(x, y, z);
  238.         s += d; t += d;
  239.         x = -1.0 + 2.f*s;
  240.         z = -1.0 + 2.f*t;
  241.         y = amplitude*sinf(freq*2.f*M_PI*t+off);
  242.         glTexCoord2f(s, t); glVertex3f(x, y, z);
  243.         off += phase;
  244.         }
  245.         glEnd();
  246.     }
  247.     }
  248. }
  249.  
  250. void display(void) {
  251.     glClear(GL_COLOR_BUFFER_BIT);
  252.  
  253.     glPushMatrix();
  254.     glTranslatef(transx, transy, 0.f);
  255.     glRotatef(rotx, 0., 1., 0.);
  256.     glRotatef(roty, 1., 0., 0.);
  257.     glScalef(10,1,10);
  258.     if (!rgb)
  259.     glColor3f(.31, .41, .97);
  260.     else
  261.     glColor3f(1.f,1.f,1.f);
  262.     glTranslatef(0.f,-1.f,0.f);
  263.     glMatrixMode(GL_TEXTURE);
  264.     glPushMatrix();
  265.     glTranslatef(ttrans[0], ttrans[1], 0.);
  266.     glScalef(10.f, 10.f,1.f);
  267.     draw_mesh();
  268.     glPopMatrix();
  269.     glMatrixMode(GL_MODELVIEW);
  270.     glPopMatrix();
  271.     glutSwapBuffers();
  272. }
  273.  
  274. void reshape(int w, int h) {
  275.     glViewport(0, 0, w, h);
  276. }
  277.  
  278. /*ARGSUSED1*/
  279. void
  280. key(unsigned char key, int x, int y) {
  281.     switch(key) {
  282.     case 'l': light(); break;
  283.     case 'f': ffunc(); break;
  284.     case 'F': Ffunc(); break;
  285.     case 't': toggle_t(); break;
  286.     case 'm': mfunc(); break;
  287.     case 'w': wire(); break;
  288.     case 'x': xfunc(); break;
  289.     case 'h': help(); break;
  290.     case '\033': exit(EXIT_SUCCESS); break;
  291.     default: break;
  292.     }
  293.     glutPostRedisplay();
  294. }
  295.  
  296. /*ARGSUSED1*/
  297. void
  298. special(int key, int x, int y) {
  299.     switch(key) {
  300.     case GLUT_KEY_UP:    up(); break;
  301.     case GLUT_KEY_DOWN:    down(); break;
  302.     case GLUT_KEY_LEFT:    left(); break;
  303.     case GLUT_KEY_RIGHT:right(); break;
  304.     }
  305. }
  306.  
  307. int main(int argc, char** argv) {
  308.     glutInitWindowSize(256, 256);
  309.     glutInit(&argc, argv);
  310.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
  311.     (void)glutCreateWindow(argv[0]);
  312.     init(argc == 1 ? "data/water1.bw" : argv[1]);
  313.     glutDisplayFunc(display);
  314.     glutKeyboardFunc(key);
  315.     glutSpecialFunc(special);
  316.     glutReshapeFunc(reshape);
  317.     glutMouseFunc(mouse);
  318.     glutMotionFunc(motion);
  319.     glutIdleFunc(animate);
  320.     glutMainLoop();
  321.     return 0;
  322. }
  323.